﻿using System.Collections.Generic;

namespace Plugins.Xml.Serialization
{
    public interface IXmlObjectSerializer :
        IXmlRuntimeSerializer
    {
        IXmlObjectSerializer Add(object obj, string value);
        IXmlObjectSerializer Remove(object obj, string value);

        int Id { get; }
        string Name { get; }
        IEnumerable<IXmlObjectSerializer> Elements { get; }
        IXmlObjectAttributeSerializer Attributes { get; }
        string this[string propertyName] { get; set; }
        string this[int index] { get; set; }

        string Deserialize();
        byte[] Serialize();
    }

    public interface IXmlRuntimeSerializer<T>
    {
        T Deserialize(IXmlPropertyReader reader, string propertyName);
        T Deserialize(IXmlPropertyReader reader, int index);

        void Serialize(T value, IXmlPropertyWriter writer, string propertyName);
        void Serialize(T value, IXmlPropertyWriter writer, int index);
    }

    public interface IXmlObjectAttributeSerializer
    {
        object this[string attributeName] { get; set; }
    }

    public interface IXmlObjectAttributeReader
    {
        object this[string attributeName] { get; }
    }

    public interface IXmlObjectAttributeWriter
    {
        object this[string attributeName] { set; }
    }

    public interface IXmlAttributeReader
    {
        IXmlObjectAttributeReader ReadAttributes { get; }
    }

    public interface IXmlAttributeWriter
    {
        IXmlObjectAttributeWriter WriteAttributes { get; }
    }

    public interface IXmlPropertyReader : IXmlAttributeReader
    {
        string Read(string propertyName);
        string Read(int index);
    }

    public interface IXmlPropertyWriter : IXmlAttributeWriter
    {
        void Write(string propertyName, string value);
        void Write(int index, string value);
    }

    internal interface IXmlRuntimePropertyReader
    {
        void Read(IXmlPropertyReader propertyReader, IObjectPropertyWriter property, string propertyName);
        void Read(IXmlPropertyReader propertyReader, IObjectPropertyWriter property, int index);
    }

    internal interface IXmlRuntimePropertyWriter
    {
        void Write(IXmlPropertyWriter propertyWriter, IObjectPropertyReader property, string propertyName);
        void Write(IXmlPropertyWriter propertyWriter, IObjectPropertyReader property, int index);
    }

    internal interface IXmlRuntimeReader
    {
        void Read(IXmlReader reader, IXmlPropertyReader node, string propertyName);
        void Read(IXmlReader reader, IXmlPropertyReader node, int index);
    }

    internal interface IXmlRuntimeWriter
    {
        void Write(IXmlWriter writer, IXmlPropertyWriter node, string propertyName);
        void Write(IXmlWriter writer, IXmlPropertyWriter node, int index);
    }

    public interface IXmlReader
    {
        void Read(IXmlPropertyReader writer, string propertyName);
        void Read(IXmlPropertyReader writer, int index);
    }

    public interface IXmlWriter
    {
        void Write(IXmlPropertyWriter writer, string propertyName);
        void Write(IXmlPropertyWriter writer, int index);
    }

    public interface IXmlRuntimeSerializer
    {
        void Serialize(object obj);
        void Deserialize(object obj);
    }

    public interface IXmlTypeSerializer<T>
    {
        T Read(IXmlPropertyReader reader, string propertyName);
        void Write(IXmlPropertyWriter writer, string propertyName, T value);

        T Read(IXmlPropertyReader reader, int index);
        void Write(IXmlPropertyWriter writer, int index, T value);
    }

    /// <summary>
    /// Свойство
    /// </summary>
    public interface IObjectProperty :
        IXmlReader,
        IXmlWriter
    {
        /// <summary>
        /// Имя свойства
        /// </summary>
        /// <returns>Имя свойства</returns>
        string Name { get; }

        /// <summary>
        /// Объект свойства
        /// </summary>
        object Object { get; }

        IObjectPropertyReader Reader { get; }
        IObjectPropertyWriter Writer { get; }
    }

    /// <summary>
    /// Свойство
    /// </summary>
    public interface IObjectPropertyReader
    {
        /// <summary>
        /// Значение свойства
        /// </summary>
        string Read();
    }

    /// <summary>
    /// Свойство
    /// </summary>
    public interface IObjectPropertyWriter
    {
        /// <summary>
        /// Значение свойства
        /// </summary>
        void Write(string value);
    }
}
